﻿using System.Security.Cryptography;
using System.Text;

namespace BlazorAdmin.Security
{
    /// <summary>
    /// DES加密算法类
    /// </summary>
    public sealed class CyptoUtils
    {
        private readonly string desKey1;
        private readonly string desKey2;
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="key1">DES加解密Key1</param>
        /// <param name="key2">DES加解密Key2</param>
        public CyptoUtils(string key1, string key2)
        {
            desKey1 = key1;
            desKey2 = key2;
        }
        /// <summary>
        /// DES加密，使用Key2进行加密
        /// </summary>
        /// <param name="sourceString"></param>
        /// <returns></returns>
        public string Encrypt(string sourceString)
        {
            return Encrypt(sourceString, desKey2, desKey2);
        }
        /// <summary>
        /// DES加密，使用Key2进行解密
        /// </summary>
        /// <param name="encryptedString"></param>
        /// <returns></returns>
        public string Decrypt(string encryptedString)
        {
            return Decrypt(encryptedString, desKey2, desKey2);
        }
        /// <summary>
        /// DES加密
        /// </summary>
        /// <param name="sourceString">需要加密的字符串</param>
        /// <param name="key">Key，如果为空字符串，则使用desKey1/></param>
        /// <param name="iv">IV如果为空字符串，则使用desKey1/></param>
        /// <returns></returns>
        public string Encrypt(string sourceString, string key, string iv)
        {
            try
            {
                key = string.IsNullOrEmpty(key) ? desKey1 : key;
                iv = string.IsNullOrEmpty(iv) ? desKey1 : iv;
                byte[] btKey = Encoding.UTF8.GetBytes(key);
                byte[] btIV = Encoding.UTF8.GetBytes(iv);

                using DES? des = DES.Create();
                using MemoryStream ms = new();
                byte[] inData = Encoding.UTF8.GetBytes(sourceString);
                try
                {
                    using (CryptoStream cs = new(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write))
                    {
                        cs.Write(inData, 0, inData.Length);
                        cs.FlushFinalBlock();
                    }

                    return Convert.ToBase64String(ms.ToArray());
                }
                catch
                {
                    return sourceString;
                }
            }
            catch { }

            return "DES加密出错";
        }
        /// <summary>
        /// DES解密
        /// </summary>
        /// <param name="encryptedString">需要解密的字符串</param>
        /// <param name="key">Key，如果为空字符串，则使用desKey1/></param>
        /// <param name="iv">IV如果为空字符串，则使用desKey1/></param>
        /// <returns></returns>
        public string Decrypt(string encryptedString, string key, string iv)
        {
            key = string.IsNullOrEmpty(key) ? desKey1 : key;
            iv = string.IsNullOrEmpty(iv) ? desKey1 : iv;

            byte[] btKey = Encoding.UTF8.GetBytes(key);
            byte[] btIV = Encoding.UTF8.GetBytes(iv);

            using DES? des = DES.Create();
            using MemoryStream ms = new();
            byte[] inData = Convert.FromBase64String(encryptedString);
            try
            {
                using (CryptoStream cs = new(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write))
                {
                    cs.Write(inData, 0, inData.Length);
                    cs.FlushFinalBlock();
                }

                return Encoding.UTF8.GetString(ms.ToArray());
            }
            catch
            {
                return encryptedString;
            }
        }
    }
}
